package com.maibow.controller.admin;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.maibow.controller.base.BaseController;
import com.maibow.entity.Page;
import com.maibow.entity.admin.Module;
import com.maibow.entity.admin.SysOperator;
import com.maibow.service.admin.IndexService;
import com.maibow.service.admin.NewRoleService;
import com.maibow.service.admin.NewUserService;
import com.maibow.service.system.CommonService;
import com.maibow.util.AppUtil;
import com.maibow.util.CommonConstants;
import com.maibow.util.DateUtil;
import com.maibow.util.PageData;
import com.maibow.util.Tools;

/**
 * 
 * 脉博网络后台管理系统
 * 包名：com.maibow.controller.admin
 * 文件名：IndexController.java
 * 作者: 吴比(Wubi)
 * 时间：2015年4月2日-上午9:06:49
 * Copyright@ 2015湖南脉博网络科技有限公司-版权所有
 *
 */
@Controller
// @RequestMapping("index")
public class IndexController extends BaseController {

    @Resource(name = "commonService")
    private CommonService commonService;

    @Resource(name = "newuserService")
    private NewUserService userService;

    @Resource(name = "newroleService")
    private NewRoleService roleService;

    @Resource(name = "indexService")
    private IndexService indexService;

    /**
     * 访问首页、登录页
     * toLogin(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@return
     * 标记：@throws Exception
     * 返回值：ModelAndView
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @RequestMapping(value = "/login_toLogin")
    public ModelAndView toLogin() throws Exception {
        ModelAndView modelView = this.getModelAndView();
        PageData pageData = new PageData();
        pageData = this.getPageData();
        pageData.put("SYSNAME", Tools.readTxtFile(CommonConstants.SYSNAME)); // 读取系统名称
        modelView.setViewName("system/main/main_login");
        modelView.addObject("pageData", pageData);
        return modelView;
    }

    /**
     * 请求登录，验证用户
     * login(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@return
     * 标记：@throws Exception
     * 返回值：Object
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @RequestMapping(value = "/login_login")
    @ResponseBody
    public Object login() throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        PageData pageData = new PageData();
        pageData = this.getPageData();
        String errInfo = "";
        String KEYDATA[] = pageData.getString("KEYDATA").replaceAll("hunanmaibownetwork", "").replaceAll("HUNANMAIBOWNETWORK", "").split(",maibow,");

        if (null != KEYDATA && KEYDATA.length == 3) {
            // shiro管理的session
            Subject currentUser = SecurityUtils.getSubject();
            Session session = currentUser.getSession();
            String sessionCode = (String) session.getAttribute(CommonConstants.SESSION_SECURITY_CODE); // 获取session中的验证码

            String code = KEYDATA[2];
            if (null == code || "".equals(code)) {
                errInfo = "nullcode"; // 验证码为空
            } else {
                String username = KEYDATA[0];
                String password = KEYDATA[1];
                pageData.put("username", username);
                if (Tools.notEmpty(sessionCode) && sessionCode.equalsIgnoreCase(code)) {
                    String passwd = new SimpleHash("SHA-1", username, password).toString(); // 密码加密
                    pageData.put("password", passwd);
                    pageData = userService.getOperatorByUsernameAndPassword(pageData);
                    if (pageData != null) {
                        if (pageData.getString("isvalid").equals("0")) {
                            errInfo = "accountnotvalid";
                        } else {
                            pageData.put("lastlogintime", DateUtil.formatTime(DateUtil.getTime()));
                            userService.updateLastLoginTime(pageData);
                            SysOperator operator = new SysOperator();
                            operator.setOperid(pageData.getInteger("operid"));
                            operator.setUsername(pageData.getString("username"));
                            operator.setPassword(pageData.getString("password"));
                            operator.setNickname(pageData.getString("nickname"));
                            operator.setEmail(pageData.getString("email"));
                            operator.setPhonenumber(pageData.getString("phonenumber"));
                            operator.setIsvalid(pageData.getString("isvalid"));
                            operator.setIsadmin(pageData.getString("isadmin"));
                            operator.setIssubaccount(pageData.getString("issubaccount"));
                            operator.setLogincount(pageData.getInteger("logincount"));
                            operator.setLoginfaiedcount(pageData.getInteger("loginfaiedcount"));
                            operator.setUnlocktime(pageData.getDate("unlocktime"));
                            operator.setLoginip(pageData.getString("loginip"));
                            operator.setParentoperid(pageData.getInteger("parentoperid"));
                            operator.setCreatorid(pageData.getLong("creatorid"));
                            operator.setCreatorname(pageData.getString("creatorname"));
                            operator.setCreatetime(pageData.getDate("createtime"));
                            operator.setLogintime(pageData.getDate("logintime"));
                            operator.setUpdatetime(pageData.getDate("updatetime"));
                            operator.setOrganid(pageData.getInteger("organid"));

                            session.setAttribute(CommonConstants.SESSION_OPERATOR, operator);
                            session.removeAttribute(CommonConstants.SESSION_SECURITY_CODE);

                            /**
                             * shiro加入身份验证
                             */
                            Subject subject = SecurityUtils.getSubject();
                            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
                            try {
                                subject.login(token);
                            } catch (AuthenticationException e) {
                                errInfo = "身份验证失败！";
                            }
                        }
                    } else {
                        errInfo = "usererror"; // 用户名或密码有误
                    }
                } else {
                    errInfo = "codeerror"; // 验证码输入有误
                }
                if (Tools.isEmpty(errInfo)) {
                    errInfo = "success"; // 验证成功
                }
            }
        } else {
            errInfo = "error"; // 缺少参数
        }
        map.put("result", errInfo);
        return AppUtil.returnObject(new PageData(), map);
    }

    /**
     * 访问系统首页
     * loginIndex(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@param page
     * 标记：@return
     * 返回值：ModelAndView
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @RequestMapping(value = "/login_index")
    public ModelAndView loginIndex(Page page) {
        ModelAndView modelView = this.getModelAndView();
        PageData pageData = new PageData();
        pageData = this.getPageData();
        try {

            // shiro管理的session
            Subject currentUser = SecurityUtils.getSubject();
            Session session = currentUser.getSession();
            List<SysOperator> operatorRoleList = new ArrayList<SysOperator>();
            SysOperator operator = (SysOperator) session.getAttribute(CommonConstants.SESSION_OPERATOR);
            if (operator != null) {
                SysOperator operatorRole = (SysOperator) session.getAttribute(CommonConstants.SESSION_OPERATOR_ROLE);
                if (null == operatorRole) {
                    operatorRoleList = userService.getUserAndRoleById(operator.getOperid());
                    operator = operatorRoleList.get(0);
                    session.setAttribute(CommonConstants.SESSION_OPERATOR_ROLE, operator);
                } else {
                    operator = operatorRole;
                    operatorRoleList = userService.getUserAndRoleById(operator.getOperid());
                }

                // 避免每次拦截用户操作时查询数据库，以下将用户所属角色权限、功能权限、操作权限都存入session
                session.setAttribute(CommonConstants.SESSION_OPERATOR_NAME, operator.getUsername()); // 放入操作员名称
                List<Module> moduleList = new ArrayList<Module>();
                if (null == session.getAttribute(CommonConstants.SESSION_MODULE_LIST)) {
                    Number ArrayROLE_IDS[] = new Number[operatorRoleList.size()];
                    int i = 0;
                    for (SysOperator sysOperator : operatorRoleList) {
                        ArrayROLE_IDS[i] = sysOperator.getRole().getRoleid();
                        i++;
                    }

                    // 查询出当前用户所有授权的模块
                    List<Module> moduleRoleList = roleService.queryAllModulesByRoleIds(ArrayROLE_IDS);
                    for (Module module : moduleRoleList) {
                        List<Module> subModuleList = new ArrayList<Module>();
                        for (Module module1 : moduleRoleList) {
                            if (module.getModuleid() == module1.getParentmoduleid()) {
                                subModuleList.add(module1);
                            }
                        }
                        if (null != subModuleList && subModuleList.size() > 0) {
                            module.setSubmodule(subModuleList);
                        }
                    }

                    // 循环模块列表，将有子模块的提取出来
                    for (Module module2 : moduleRoleList) {
                        if (module2.getParentmoduleid() == 0) {
                            moduleList.add(module2);
                        }
                    }

                    session.setAttribute(CommonConstants.SESSION_MODULE_LIST, moduleList);
                } else {
                    moduleList = (List<Module>) session.getAttribute(CommonConstants.SESSION_MODULE_LIST);
                }

                String username = session.getAttribute(CommonConstants.SESSION_OPERATOR_NAME).toString();
                this.getRemortIP(username);

                // FusionCharts 报表
                String strXML = "<graph caption='前12个月订单销量柱状图' xAxisName='月份' yAxisName='值' decimalPrecision='0' formatNumberScale='0'><set name='2013-05' value='4' color='AFD8F8'/><set name='2013-04' value='0' color='AFD8F8'/><set name='2013-03' value='0' color='AFD8F8'/><set name='2013-02' value='0' color='AFD8F8'/><set name='2013-01' value='0' color='AFD8F8'/><set name='2012-01' value='0' color='AFD8F8'/><set name='2012-11' value='0' color='AFD8F8'/><set name='2012-10' value='0' color='AFD8F8'/><set name='2012-09' value='0' color='AFD8F8'/><set name='2012-08' value='0' color='AFD8F8'/><set name='2012-07' value='0' color='AFD8F8'/><set name='2012-06' value='0' color='AFD8F8'/></graph>";
                modelView.addObject("strXML", strXML);
                // FusionCharts 报表

                modelView.setViewName("system/main/main_index");
                modelView.addObject("operator", operator);
                modelView.addObject("moduleList", moduleList);
            } else {
                modelView.setViewName("system/main/main_login");// session失效后跳转登录页面
            }

        } catch (Exception e) {
            modelView.setViewName("system/main/main_login");
            logger.error(e.getMessage(), e);
        }
        pageData.put("SYSNAME", Tools.readTxtFile(CommonConstants.SYSNAME)); // 读取系统名称
        modelView.addObject("pageData", pageData);
        return modelView;
    }

    /**
     * 进入tab标签
     * mainTab(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@return
     * 返回值：String
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @RequestMapping(value = "/mainTab")
    public String mainTab() {
        return "system/main/main_tab";
    }

    /**
     * 进入首页后的默认页面
     * loginDefault(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@return
     * 返回值：String
     * 作者：吴比(Wubi)
     * 
     * @throws Exception
     * 
     * @exception
     * @since 1.0.0
     */
    @RequestMapping(value = "/login_default")
    public ModelAndView loginDefault() throws Exception {
        ModelAndView modelView = this.getModelAndView();
        PageData pageData = new PageData();
        pageData = this.getPageData();

        SysOperator operator = commonService.getCurrentOperator();
        pageData.put("organ_id", Integer.valueOf(operator.getOrganid()));
        pageData.put("is_admin", Integer.valueOf(operator.getIsadmin()));

        // 关注商户总人数
        PageData favoriteCountPageData = indexService.queryFavoriteCount(pageData);
        pageData.put("favorite_count", favoriteCountPageData.get("favorite_count"));

        PageData memberPageData = indexService.queryMemberCount(pageData);
        pageData.put("member_count", memberPageData.get("member_count"));

        // 今日订单数;今日订单相比昨日涨跌幅度
        PageData today_order_countPageData = indexService.queryTodayOrderCount(pageData);
        pageData.put("today_order_count", today_order_countPageData.get("today_order_count"));

        PageData yes_order_countPageData = indexService.queryYesOrderCount(pageData);
        pageData.put("yes_order_count", yes_order_countPageData.get("yes_order_count"));

        BigDecimal today_order_count = new BigDecimal(today_order_countPageData.get("today_order_count").toString());
        BigDecimal yes_order_count = new BigDecimal(yes_order_countPageData.get("yes_order_count").toString());

        // 今日礼单数;今日礼单对比昨日涨跌幅度
        PageData today_gift_countPageData = indexService.queryTodayGiftCount(pageData);
        pageData.put("today_gift_count", today_gift_countPageData.get("today_gift_count"));

        PageData yes_gift_countPageData = indexService.queryYesGiftCount(pageData);
        pageData.put("yes_gift_count", yes_gift_countPageData.get("yes_gift_count"));

        BigDecimal today_gift_count = new BigDecimal(today_gift_countPageData.get("today_gift_count").toString());
        BigDecimal yes_gift_count = new BigDecimal(yes_gift_countPageData.get("yes_gift_count").toString());

        // 酒水库存数量
        PageData store_numberPageData = indexService.queryProductStoreCount(pageData);
        pageData.put("store_number", store_numberPageData.get("store_number"));

        // 营销经理人数
        PageData marketing_mgr_countPageData = indexService.queryMarketingMgrCount(pageData);
        pageData.put("marketing_mgr_count", marketing_mgr_countPageData.get("marketing_mgr_count"));

        // 商户桌台数
        PageData table_countPageData = indexService.queryTablesCount(pageData);
        pageData.put("table_count", table_countPageData.get("table_count"));
        modelView.addObject("pageData", pageData);
        modelView.setViewName("system/main/main_default");
        return modelView;
    }

    /**
     * 用户注销
     * logout(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@return
     * 返回值：ModelAndView
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @RequestMapping(value = "/logout")
    public ModelAndView logout() {
        ModelAndView modelView = this.getModelAndView();
        PageData pageData = new PageData();

        // shiro管理的session
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();

        session.removeAttribute(CommonConstants.SESSION_OPERATOR);
        session.removeAttribute(CommonConstants.SESSION_OPERATOR_NAME);
        session.removeAttribute(CommonConstants.SESSION_OPERATOR_ROLE);
        session.removeAttribute(CommonConstants.SESSION_MODULE_LIST);
        session.removeAttribute(CommonConstants.SESSION_OPERATOR_PAGEDATAS);

        // shiro销毁登录
        Subject subject = SecurityUtils.getSubject();
        subject.logout();

        pageData = this.getPageData();
        String msg = pageData.getString("msg");
        pageData.put("msg", msg);

        pageData.put("SYSNAME", Tools.readTxtFile(CommonConstants.SYSNAME)); // 读取系统名称
        modelView.setViewName("system/main/main_login");
        modelView.addObject("pageData", pageData);
        return modelView;
    }

    /**
     * 获取登录用户的IP
     * getRemortIP(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@param username
     * 标记：@throws Exception
     * 返回值：void
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    public void getRemortIP(String username) throws Exception {
        PageData pageData = new PageData();
        HttpServletRequest request = this.getRequest();
        String loginip = "";
        if (request.getHeader("x-forwarded-for") == null) {
            loginip = request.getRemoteAddr();
        } else {
            loginip = request.getHeader("x-forwarded-for");
        }

        pageData.put("username", username);
        pageData.put("loginip", loginip);
        userService.saveLoginIP(pageData);
    }
}